home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / viewwrld / viewwrld.lha / viewworld / lgd / mf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-21  |  8.6 KB  |  316 lines

  1. /* $Id: mf.c,v 1.7 89/09/20 17:49:19 mbp Exp $
  2.  *
  3.  * mf.c: metafile procedures
  4.  */
  5.  
  6. /************************************************************************
  7.  *        Copyright (C) 1989 by Mark B. Phillips                  *
  8.  *                                     *
  9.  * Permission to use, copy, modify, and distribute this software and    *
  10.  * its documentation for any purpose and without fee is hereby granted, *
  11.  * provided that the above copyright notice appear in all copies and    *
  12.  * that both that copyright notice and this permission notice appear in *
  13.  * supporting documentation, and that the name of Mark B. Phillips or   *
  14.  * the University of Maryland not be used in advertising or publicity   *
  15.  * pertaining to distribution of the software without specific, written *
  16.  * prior permission.  This software is provided "as is" without express *
  17.  * or implied warranty.                                                 *
  18.  ************************************************************************/
  19.  
  20. #include    <stdio.h>
  21. #include    "lgd.h"
  22. #include    "internal.h"
  23. #include    "mf.h"
  24.  
  25. /************************************************************************
  26.  *              PUBLIC DEFINITIONS                *
  27.  ************************************************************************/
  28.  
  29. /* Maximum value of data stored in MF: */
  30. mfe    MF_max_val;
  31.  
  32. /* Metafile commands: */
  33. mfe    MF_begin_segment;
  34. mfe    MF_end_segment;
  35. mfe    MF_pen_up;
  36. mfe    MF_pen_down;
  37. mfe    MF_point;
  38. mfe    MF_line_style;
  39. mfe    MF_color;
  40.  
  41. /* Largest command value: */
  42. mfe    MF_max_command;
  43.  
  44. /* Global metafile error flag */
  45. char *mf_error=NULL;
  46.  
  47. /* Length of metafile (number of words): */
  48. #define        MF_LENGTH        50000
  49.  
  50. /* The metafile itself: */
  51. mfe    mf_metafile[MF_LENGTH];
  52.  
  53. /*--------------------End of Public Definitions-------------------------*/
  54.  
  55. /************************************************************************
  56.  *             PRIVATE DEFINITIONS                *
  57.  ************************************************************************/
  58.  
  59. /* Address of first entry in MF: */
  60. static mfa    mf_start;
  61.  
  62. /* Address of last entry in MF (mf_end=0 means empty MF): */
  63. static mfa    mf_end;    
  64.  
  65. /* NOTE: The above defs mean that at any given time, the MF contains
  66.  * mf_end-mf_start+1 words at addresses mf_start through and including
  67.  * mf_end */
  68.  
  69. /*--------------------End of Private Definitions------------------------*/
  70.  
  71. /************************************************************************
  72.  *              PUBLIC PROCEDURES                *
  73.  ************************************************************************/
  74.  
  75. /*-----------------------------------------------------------------------
  76.  * Function:     mf_initialize
  77.  * Description:  Initialize the MetaFile
  78.  * Arguments:    (none)
  79.  * Returns:      nothing
  80.  */
  81. mf_initialize()
  82. {
  83.   mf_start         = 1;
  84.   mf_end        = 0;
  85.   MF_max_val        = 65500;
  86.   MF_begin_segment    = MF_max_val+1;
  87.   MF_end_segment    = MF_max_val+2;
  88.   MF_pen_up        = MF_max_val+3;
  89.   MF_pen_down        = MF_max_val+4;
  90.   MF_point        = MF_max_val+5;
  91.   MF_line_style        = MF_max_val+6;
  92.   MF_color        = MF_max_val+7;
  93.   MF_max_command    = MF_max_val+7;
  94. }
  95.  
  96. /*-----------------------------------------------------------------------
  97.  * Function:     mf_save
  98.  * Description:  Write MetaFile to a disk file
  99.  * Arguments IN: fp: file to write to
  100.  * Returns:      nothing
  101.  * Notes:        fp should point to a file which has been opened
  102.  *               for binary writing.
  103.  */
  104. mf_save( fp )
  105.      FILE *fp;
  106. {
  107.   mfa first,last,address,length;
  108.   mfe entry;
  109.   int items_written;
  110.  
  111.   /*
  112.    *********************
  113.    * THIS IS FORMAT 3  *
  114.    *********************
  115.    */
  116.   first = mf_first_addr();
  117.   last = mf_last_addr();
  118.   length = last - first + 1;
  119.   items_written =        /* Write length */
  120.     fwrite( (char*)&length, sizeof(mfa), 1, fp );
  121.   if (items_written!=1) {
  122.     mf_error = E_sm_bad_write;
  123.     return;
  124.   }
  125.   /* Write metafile: */
  126.   for (address=first; address<=last; ++address) {
  127.     entry = mf_peek(address);
  128.     items_written = fwrite( (char*)&entry,
  129.                  sizeof(mfe),1,fp );
  130.     if (items_written!=1) {
  131.       mf_error = E_sm_bad_write;
  132.       return;
  133.     }
  134.   }
  135. }
  136.  
  137. /*-----------------------------------------------------------------------
  138.  * Function:     mf_load
  139.  * Description:  Read a MetaFile from a disk file
  140.  * Arguments IN: fp: file to write to
  141.  * Returns:      nothing
  142.  * Notes:        fp should point to a file which has been opened
  143.  *               for binary reading
  144.  */
  145. mf_load( fp )
  146.      FILE *fp;
  147. {
  148.   mfe entry;
  149.   mfa length;
  150.   int items_read;
  151.   
  152.   /*
  153.    *********************
  154.    * THIS IS FORMAT 3  *
  155.    *********************
  156.    */
  157.   mf_initialize();
  158.   items_read =            /* Read length */
  159.     fread( (char*)&length,sizeof(mfa), 1, fp);
  160.   if (items_read!=1) {
  161.     mf_error = E_sm_bad_write;
  162.     return;
  163.   }
  164.   /* Read metafile: */
  165.   while ( (length>0) && (mf_error==NULL) )  {
  166.     items_read = fread((char*)&entry, sizeof(mfe), 1, fp );
  167.     if (items_read!=1) {
  168.       mf_error = E_sm_bad_write;
  169.       return;
  170.     }
  171.     mf_append( entry );
  172.     --length;
  173.   }
  174. }
  175.  
  176. /*-----------------------------------------------------------------------
  177.  * Function:     mf_first_addr
  178.  * Description:  Get the address of the first entry in the MF
  179.  * Arguments:    (none)
  180.  * Returns:      The address of the first entry
  181.  */
  182. mfa mf_first_addr()
  183. {
  184.   return( mf_start );
  185. }
  186.  
  187. /*-----------------------------------------------------------------------
  188.  * Function:     mf_last_addr
  189.  * Description:  Get the address of the last entry in the MF
  190.  * Arguments:    (none)
  191.  * Returns:      The address of the last entry
  192.  * Notes:        This is the last actually used entry -- not the
  193.  *               last theoretical position in the MF.
  194.  */
  195. mfa mf_last_addr()
  196. {
  197.   return( mf_end );
  198. }
  199.  
  200. /*-----------------------------------------------------------------------
  201.  * Function:     mf_poke
  202.  * Description:  Store an entry in the MF
  203.  * Arguments IN: address: address to write to
  204.  *               value: value to write at address
  205.  * Returns:      nothing
  206.  */
  207. mf_poke( address, value )
  208.      mfa address;
  209.      mfe value;
  210. {
  211.   mf_metafile[address] = value;
  212. }
  213.  
  214. /*-----------------------------------------------------------------------
  215.  * Function:     mf_append
  216.  * Description:  Append an entry to end of MF
  217.  * Arguments IN: value: value to append
  218.  * Returns:      nothing
  219.  * Notes:        Sets an error if there is no more room in MF
  220.  */
  221. mf_append( value )
  222.      mfe value;
  223. {
  224.   if (MF_LENGTH-mf_end<1) {
  225.     mf_error = E_mf_overflow;
  226.     return;
  227.   }
  228.   mf_poke( ++mf_end, value );
  229. }
  230.  
  231. /*-----------------------------------------------------------------------
  232.  * Function:     mf_append_array
  233.  * Description:  Append an array of entries to end of MF
  234.  * Arguments IN: value_array: array to append
  235.  *               n: length of (number of entries in) value array
  236.  * Returns:      nothing
  237.  * Notes:        Sets an error if there is not enough room in MF
  238.  */
  239. mf_append_array( value_array, n )
  240.      mfe value_array[];
  241.      int n;
  242. {
  243.   if (MF_LENGTH-mf_end<n) {
  244.     mf_error = E_mf_overflow;
  245.     return;
  246.   }
  247.   while (n) {
  248.     mf_poke( ++mf_end, *value_array );
  249.     ++value_array;
  250.     --n;
  251.   }
  252. }
  253.  
  254. /*-----------------------------------------------------------------------
  255.  * Function:     mf_truncate
  256.  * Description:  Truncate MF at a given point
  257.  * Arguments IN: address: address to truncate at
  258.  * Returns:      nothing
  259.  * Notes:        After truncation, address is the address of the
  260.  *               last entry in MF.  If address is out of range,
  261.  *               an error is set.
  262.  */
  263. mf_truncate( address )
  264.      mfa address;
  265. {
  266.   if (   (address<mf_start-1)
  267.       || (address>MF_LENGTH ) ) {
  268.     mf_error = E_bad_trunc;
  269.     return;
  270.   }
  271.   mf_end = address;
  272. }
  273.  
  274. /*-----------------------------------------------------------------------
  275.  * Function:     mf_compress
  276.  * Description:  Compress out a region of the MF
  277.  * Arguments IN: first: first address of region to take out
  278.  *               last: last address of region to take out
  279.  * Returns:      nothing
  280.  * Notes:        The region compressed out is first thru last, inclusive.
  281.  *               If first or last is out of range, an error is set.
  282.  */
  283. mf_compress( first, last )
  284.      register mfa first;
  285.      register mfa last;
  286. {
  287.   if (    (first<mf_start)
  288.       || (last>mf_end)
  289.       || (first>last)      ) {
  290.     mf_error = E_bad_compress;
  291.     return;
  292.   }
  293.   while (last<mf_end) {
  294.     ++last;
  295.     mf_metafile[first] = mf_metafile[last];
  296.     ++first;
  297.   }
  298.   mf_end = first - 1;
  299. }      
  300.  
  301. /*-----------------------------------------------------------------------
  302.  * Function:     mf_length
  303.  * Description:  Get the total potential length of the MetaFile
  304.  * Arguments:    (none)
  305.  * Returns:      the number of entry positions
  306.  * Notes:        This is the maximum possible length; not just the
  307.  *               currently used part.
  308.  */
  309. mfa
  310. mf_length()
  311. {
  312.   return( (mfa) MF_LENGTH );
  313. }
  314.  
  315. /*---------------------End of Public Procedures-------------------------*/
  316.